package com.ckx.service.impl;

import com.ckx.domain.ResponseResult;
import com.ckx.domain.entity.LoginUserDetails;
import com.ckx.domain.entity.User;
import com.ckx.domain.vo.BlogUserLoginVo;
import com.ckx.domain.vo.UserInfoVo;
import com.ckx.enums.AppHttpCodeEnum;
import com.ckx.exception.SystemException;
import com.ckx.service.LoginService;
import com.ckx.utils.BeanCopyUtil;
import com.ckx.utils.JwtUtil;
import com.ckx.utils.RedisCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;

import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 用户登录模块
 */
@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private RedisCache redisCache;

    @Override
    public BlogUserLoginVo login(User user) {
        //二参登录校验使用
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(user.getUserName(), user.getPassword());
        //默认下走缓存中生成的账户密码进行校验，配置后走 UserDetailsService(PasswordEncoder.match(password))
        //密码正确 校验成功返回对应数据
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        if (Objects.isNull(authenticate)) {
            throw new SystemException(AppHttpCodeEnum.LOGIN_ERROR);
        }
        LoginUserDetails userDetail = (LoginUserDetails) authenticate.getPrincipal();
        String userId = userDetail.getUser().getId().toString();
        //生成 jwt令牌 token
        String token = JwtUtil.createJWT(userId);
        UserInfoVo userInfoVo = BeanCopyUtil.copyBean(userDetail.getUser(), UserInfoVo.class);

        //存入 Redis
        redisCache.setCacheObject("BlogLogin:" + userId, userDetail, 60, TimeUnit.MINUTES);
        //返回vo
        return new BlogUserLoginVo(token, userInfoVo);

    }

    @Override
    public void logout() {

        //获取token 解析获取userid
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUserDetails loginUser = (LoginUserDetails) authentication.getPrincipal();
        //获取userid
        Long userId = loginUser.getUser().getId();
        //删除redis中的用户信息
        redisCache.deleteObject("BlogLogin:" + userId);

    }
}
